﻿using System;
using System.Collections.ObjectModel;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
using System.Diagnostics;
using System.Security;

namespace Cherry.Agile.ServiceModel.Interceptor
{
    /// <summary>
    /// 自定义服务扩展
    /// </summary>
    [AttributeUsage(AttributeTargets.Class| AttributeTargets.Interface)]
    public class ServiceInterceptorAttribute : Attribute, IServiceBehavior
    {
        public ServiceInterceptorAttribute()
        {
            IsBidirectional = true;
            PolicyLevel = PolicyLevel.Enterprise;
        }
        /// <summary>
        /// 标识是否支扩展消息头附加
        /// </summary>
        public bool IsBidirectional { get; set; }

        /// <summary>
        /// 安全区域
        /// </summary>
        public PolicyLevel PolicyLevel { get; set; }

        /// <summary>
        /// 增加一个Operation Interceptor
        /// </summary>
        /// <param name="operationMethod">方法名称</param>
        /// <returns><see cref="Cherry.Agile.ServiceModel.Interceptor.OperationInterceptorAttribute"/></returns>
        protected OperationInterceptorAttribute CreateOperationInterceptor(string operationMethod)
        {
            return new OperationInterceptorAttribute(operationMethod);
        }

        /// <summary>
        /// 用于更改运行时属性值或插入自定义扩展对象
        /// </summary>
        /// <param name="serviceDescription">服务说明</param>
        /// <param name="host">当前正在生成的宿主</param>
        public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase host)
        {
            
            foreach (ServiceEndpoint endpoint in serviceDescription.Endpoints)
            {
               
                var bidirectional = Unity.GetIsBidirectionalSet(endpoint.Contract.ContractType,IsBidirectional);

                //var atrs = endpoint.Contract.ContractType.GetCustomAttributes(typeof(ServiceInterceptorAttribute), true);
                //if (atrs.Length > 0)
                //    bidirectional = bidirectional || (atrs[0] as ServiceInterceptorAttribute).IsBidirectional;

                endpoint.Behaviors.Add(new EndpointInterceptorAttribute(bidirectional, this.PolicyLevel));
                foreach (OperationDescription operation in endpoint.Contract.Operations)
                {
                    bool checkresult = false;
                    foreach (IOperationBehavior behavior in operation.Behaviors)
                    {
                        if (behavior is OperationInterceptorAttribute)
                        {
                            checkresult = true;
                            break;
                        }
                    }
                    if (!checkresult)
                    {
                        operation.Behaviors.Add(CreateOperationInterceptor(operation.Name));
                        Trace.TraceInformation("ServiceInterceptorAttribute\tapply operation intercetor into " + operation.Name);
                    }
                }
            }
        }

        /// <summary>
        /// 用于向绑定元素传递自定义数据，以支持协定实现
        /// </summary>
        /// <param name="serviceDescription">服务的服务说明</param>
        /// <param name="serviceHostBase">服务的宿主</param>
        /// <param name="endpoints">服务的终结点</param>
        /// <param name="bindingParameters">绑定元素可访问的自定义对象</param>
        public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase
            , Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters)
        {

        }

        /// <summary>
        /// 用于检查服务宿主和服务说明，从而确定服务是否可成功运行
        /// </summary>
        /// <param name="serviceDescription">服务的服务说明</param>
        /// <param name="serviceHostBase">服务的宿主</param>
        public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
        {
        }        
    }
}
